﻿import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:vischat/core/controller/auth_service.dart';
import 'package:vischat/core/utils/tencent/conversation_util.dart';
import 'package:vischat/data/datasources/local/secure_local.dart';
import 'package:vischat/generated/route_table.dart';
import 'package:vischat/shared/widgets/view_list/view_list_controller.dart';

class SocializeController extends ViewListController<V2TimConversation> {

  final AuthService _authService;
  final SecureLocal _secureLocal;
  final Logger _logger;
  SocializeController(this._authService, this._secureLocal, this._logger) : super(perPage: 100);

  final _nextSeq = '0'.obs;
  final _isSyncing = true.obs;

  // 快速查找表
  final Map<String, V2TimConversation> _conversationMap = {};
  // 置顶会话ID集合
  final Set<String> _pinnedIds = {};
  // 排序状态缓存
  int _lastMaxTimestamp = 0;
  final _scrollController = ScrollController();

  get scrollController => _scrollController;

  @override
  onInit() {
    _initListeners();
    super.onInit();
  }

  /// 判断置顶
  bool isPinned(String conversationId) => _pinnedIds.contains(conversationId);

  /// 置顶/取消置顶
  Future<void> togglePin(String conversationId) async {
    if (_pinnedIds.contains(conversationId)) {
      _pinnedIds.remove(conversationId);
      await ConversationUtil.pinConversation(
        conversationID: conversationId,
        isPinned: false,
      );
    } else {
      _pinnedIds.add(conversationId);
      await ConversationUtil.pinConversation(
        conversationID: conversationId,
        isPinned: true,
      );
    }
    _sortConversations();
  }

  /// 查询
  void search() {}

  /// 进入聊天
  void goChat(V2TimConversation conversation) async {
    Get.toNamed(
      RouteTable.CHAT,
      preventDuplicates: false,
      arguments: {'conversation': conversation},
    );
  }

  @override
  Future<List<V2TimConversation>?> loadData(int page, int perPage) async {
    List<V2TimConversation?> conversationList;
    if (_isSyncing.value) {
      conversationList = _secureLocal.getConversations();
    } else {
      if (!hasMore.value && page > 1) return [];
      final result = await ConversationUtil.getConversationList(
        count: perPage,
        nextSeq: page == 1 ? '0' : _nextSeq.value,
      );
      if (result == null) {
        _logger.e('加载会话列表出错');
        state.value = ViewState.error;
        return null;
      }
      conversationList = result.conversationList ?? [];
      _nextSeq.value = result.nextSeq ?? '0';
      hasMore.value = !(result.isFinished ?? true);
      _secureLocal.saveConversations(conversationList);
    }
    _countUnread(conversationList);
    return conversationList.whereType<V2TimConversation>().toList();
  }

  /// 初始化监听
  Future<void> _initListeners() async {
    await ConversationUtil.addConversationListener(
      V2TimConversationListener(
        onSyncServerStart: () {
          // 同步服务器会话开始
          _logger.i("开始同步会话列表");
        },
        onSyncServerFinish: () async {
          // 同步服务器会话完成
          _logger.i("同步会话列表完成");
          _isSyncing.value = false;
          await load(isRefresh: true);
        },
        onSyncServerFailed: () {
          // 同步服务器会话失败
          _logger.i("同步会话列表失败");
        },
        onConversationChanged: (List<V2TimConversation> conversationList) {
          _logger.i("有会话更新");
          // 有会话更新
          _handleBatchUpdates(conversationList);
          _countUnread(conversationList);
        },
        onNewConversation: (List<V2TimConversation> conversationList) {
          // 有会话新增
          _handleBatchUpdates(conversationList);
          _countUnread(conversationList);
        },
        onTotalUnreadMessageCountChanged: (int totalUnreadCount) {
          // 会话未读总数变更通知
          _logger.i("有新未读消息");
        },
      ),
    );
  }

  /// 批量更新处理
  void _handleBatchUpdates(List<V2TimConversation>? updatedConvs) {
    if (updatedConvs == null || updatedConvs.isEmpty) return;

    bool needsUpdate = false;
    bool needsSort = false;
    int newMaxTimestamp = _lastMaxTimestamp;

    // 增量更新检测
    for (final newConv in updatedConvs) {
      final oldConv = _conversationMap[newConv.conversationID];
      final newTimestamp = newConv.lastMessage?.timestamp ?? 0;

      if (oldConv == null || !_isConvEqual(oldConv, newConv)) {
        _conversationMap[newConv.conversationID] = newConv;
        needsUpdate = true;

        // 检测排序条件
        if (newTimestamp > newMaxTimestamp ||
            (oldConv != null &&
                isPinned(newConv.conversationID) !=
                    isPinned(oldConv.conversationID))) {
          needsSort = true;
          newMaxTimestamp =
              newTimestamp > newMaxTimestamp ? newTimestamp : newMaxTimestamp;
        }
      }
    }

    // 优化：仅在必要时更新
    if (needsUpdate) {
      list.assignAll(_conversationMap.values.toList());
      if (needsSort) _sortConversations();
    }
  }

  /// 排序
  void _sortConversations() {
    list.sort((a, b) {
      final aPinned = isPinned(a.conversationID);
      final bPinned = isPinned(b.conversationID);

      if (aPinned != bPinned) {
        return aPinned ? -1 : 1;
      }
      return (b.lastMessage?.timestamp ?? 0).compareTo(
        a.lastMessage?.timestamp ?? 0,
      );
    });
    _lastMaxTimestamp = list.firstOrNull?.lastMessage?.timestamp ?? 0;
  }

  /// 精确比较
  bool _isConvEqual(V2TimConversation a, V2TimConversation b) {
    return a.conversationID == b.conversationID &&
        a.unreadCount == b.unreadCount &&
        a.lastMessage?.msgID == b.lastMessage?.msgID &&
        a.lastMessage?.timestamp == b.lastMessage?.timestamp;
  }

  /// 计算未读数量
  void _countUnread(List<V2TimConversation?> conversations) {
    final newUnread = conversations.fold(
      0,
      (sum, c) => sum + (c?.unreadCount ?? 0),
    );
    if (newUnread != _authService.unread.value) {
      _authService.unread.value = newUnread;
    }
  }
}
